import { usePageColorStore } from '@/stores'
import { aesDecrypt } from '@/utils/crypto'

/**
 * 禁用黑色主题
 */
export const disableBlackTheme = () => {
  const pageColorStore = usePageColorStore()
  if (pageColorStore.isDark) {
    document.documentElement.classList.remove('dark')
    document.body.removeAttribute('arco-theme')
  }
}

/**
 * 格式化成想要的时间格式
 * @param {要格式化的字符串} isoString
 * @returns
 */
export const formatDateTime = (isoString) => {
  // 创建一个 Date 对象
  const date = new Date(isoString)

  // 提取年、月、日、小时、分钟和秒
  const year = date.getFullYear()
  const month = String(date.getMonth() + 1).padStart(2, '0') // 月份从0开始，需要加1
  const day = String(date.getDate()).padStart(2, '0')
  const hours = String(date.getHours()).padStart(2, '0')
  const minutes = String(date.getMinutes()).padStart(2, '0')
  const seconds = String(date.getSeconds()).padStart(2, '0')

  // 格式化输出字符串
  return `${year}年${month}月${day}日 ${hours}:${minutes}:${seconds}`
}

/**
 * 获取html字符串里面的文本
 * @param {html字符串} html
 * @returns
 */
export const getTextByHtml = (html) => {
  // 创建一个临时的DOM元素来存放HTML字符串
  const tempDiv = document.createElement('div')
  tempDiv.innerHTML = html

  // 递归地遍历DOM树，并收集所有的文本节点
  function getText(element) {
    let text = ''
    Array.from(element.childNodes).forEach((node) => {
      if (node.nodeType === Node.TEXT_NODE) {
        text += node.textContent
      } else if (node.nodeType === Node.ELEMENT_NODE) {
        text += getText(node)
      }
    })
    return text
  }

  // 调用递归函数并返回结果
  return getText(tempDiv)
}

/**
 * 获取当前距离给定时间字符串差多少天
 * @param {时间字符串} dateString
 * @returns
 */
export const daysDifferenceFromNow = (dateString) => {
  // 创建一个 Date 对象来表示给定的日期和时间
  const givenDate = new Date(dateString)

  // 创建一个 Date 对象来表示当前的日期和时间（默认为本地时间）
  // 但是，由于给定的日期字符串包含 UTC 时间信息（+00:00），
  // 为了保持一致，我们应该也使用 UTC 时间来表示当前日期和时间。
  // 然而，JavaScript 的 Date 对象在处理时区时有些复杂。
  // 为了简化，我们可以假设服务器或运行环境已经设置了正确的时区，
  // 或者我们总是使用 UTC 时间进行计算（这取决于你的具体需求）。
  // 在这里，为了演示，我们将使用本地时间，但请注意时区差异可能会影响结果。
  // 如果你想要严格使用 UTC 时间，请确保你的环境支持这一点，
  // 或者在创建 Date 对象时使用 Date.UTC() 方法和相应的参数。
  const now = new Date()

  // 如果你想要使用 UTC 时间进行比较（推荐，以避免时区问题），
  // 可以使用以下代码替换上面的 now 变量：
  // const nowUTC = new Date(Date.UTC(now.getFullYear(), now.getMonth(), now.getDate(), now.getHours(), now.getMinutes(), now.getSeconds(), now.getMilliseconds()));
  // 但是，由于我们只知道给定日期字符串是 UTC 时间，而不知道当前时间是否也是 UTC，
  // 所以这里我们仍然使用本地时间的 now 变量，并提醒注意时区问题。
  // 在实际应用中，你应该根据你的需求和环境来决定是否使用 UTC 时间。

  // 计算两个日期之间的毫秒差
  const diffInMilliseconds = givenDate - now

  // 将毫秒差转换为天数差
  const diffInDays = diffInMilliseconds / (1000 * 60 * 60 * 24)

  // 返回天数差（可能是负数，表示给定日期在当前日期之前）
  return Number(diffInDays.toFixed(0))
}

/**
 * 信件内容格式化专属函数
 * @param {要格式化的数据} data
 */
export const formattedDataByLetterInfo = (data) => {
  if (!Array.isArray(data)) {
    data = [data]
  }

  for (let item of data) {
    if (item.title != null) {
      item.title = aesDecrypt(item.title)
    }
    if (item.content != null) {
      item.contentText = getTextByHtml(aesDecrypt(item.content))
      item.content = aesDecrypt(item.content)
    }
    // 保留原始的时间戳
    item.orgSendTime = item.sendTime
    item.orgWriteTime = item.writeTime
    if (item.sendTime === undefined || item.sendTime == null) {
      item.sendTime = '未设置'
    } else {
      item.sendTime = formatDateTime(item.sendTime)
    }
    if (item.writeTime === undefined || item.writeTime == null) {
      item.writeTime = '未设置'
    } else {
      item.writeTime = formatDateTime(item.writeTime)
    }
  }
  return data
}

/**
 * 去掉最外层的元素的包裹
 * @param {html字符串} htmlString
 * @returns
 */
export const removeOuterElement = (htmlString) => {
  // 创建一个临时容器来解析HTML字符串
  const tempDiv = document.createElement('div')
  tempDiv.innerHTML = htmlString.trim()

  // 获取最外层的元素
  const outerElement = tempDiv.firstChild

  // 如果没有子节点，直接返回原始字符串（可能是纯文本或空字符串）
  if (!outerElement || !outerElement.hasChildNodes()) {
    return htmlString
  }

  // 获取最外层元素的所有子节点
  let innerHTML = ''
  Array.from(outerElement.childNodes).forEach((childNode) => {
    innerHTML += childNode.outerHTML
  })

  // 返回去掉最外层包裹后的HTML字符串
  return innerHTML
}
